const PENDING = 'pending'; // 等待 状态
const FULFILLED = 'fulfilled'; // 成功 状态
const REJECTED = 'rejected'; // 失败 状态

class myPromise {
  constructor(executor) {
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (e) {
      this.reject(e);
    }
  }
  // 当前的状态
  state = PENDING;
  // 结果值
  result = undefined;
  // 成功回调
  successCallbackList = [];
  // 失败回调
  failCallbackList = [];

  resolve(val) {
    // 状态不是 pending 就直接返回
    if (this.state !== PENDING) return;
    // 修改状态为成功状态
    this.state = FULFILLED;
    // 绑定成功结果
    this.result = val;

    this._nextTick(() => {
      // 多次的then需要按顺序执行成功的回调函数
      while (this.successCallbackList.length) this.successCallbackList.shift()(this.result);
    });
  }

  reject(val) {
    // 状态不是 pending 就直接返回
    if (this.state !== PENDING) return;
    // 修改状态为失败状态
    this.state = REJECTED;
    // 绑定失败结果
    this.result = val;

    this._nextTick(() => {
      // 多次的then需要按顺序执行失败的回调函数
      while (this.failCallbackList.length) this.failCallbackList.shift()(this.result);
    });
  }

then(successCb, failCb) {
  // 参数处理
  successCb = successCb ? successCb : (value) => value;
  failCb = failCb ? failCb : (errStr) => {throw errStr};

  const thenPromise = new myPromise((thenResolve, thenReject) => {
    this.successCallbackList.push((thenResult) => {
      try {
        // 执行成功回调函数，拿到返回值
        thenResult = successCb(thenResult);
        // 如果thenResult 是一个myPromise对象
        if (thenResult instanceof myPromise) {
          // thenResolve 需要拿到thenResult这个myPromise对象的result
          return thenResult.then(thenResolve, thenReject);
        }
        // resolve出这个值，链式调用的时候后面的then就可以拿到了
        thenResolve(thenResult);
      } catch (e) {
        thenReject(e);
      }
    });

    this.failCallbackList.push((thenResult) => {
      try {
        // 执行失败回调函数，拿到返回值
        thenResult = failCb(thenResult);
        // 如果thenResult 是一个myPromise对象
        if (thenResult instanceof myPromise) {
          // thenResolve 需要拿到thenResult这个myPromise对象的result
          return thenResult.then(thenResolve, thenReject);
        }
        // 失败函数的返回值是被下一个then成功回调接收的  这里需要执行thenResolve
        thenResolve(thenResult);
      } catch (e) {
        thenReject(e);
      }
    });
  });
  return thenPromise;
}

  // Promise -> MutationObserver -> setImmediate -> setTimeout
  _nextTick(cb) {
    // 执行回调函数
    const p = Promise.resolve();
    p.then(cb);
    // -------
    // MutationObserver 实现微任务
    // let ob = new MutationObserver(() => {
    //   cb();
    //   // 用完销毁
    //   ob.disconnect();
    //   ob = null;
    // });
    // ob.observe(document.body, { attributes: true });
    // document.body.setAttribute('_yl', Math.random());
    // -------
    // setTimeout 实现宏任务
    // setTimeout(cb, 0);
  }
}
function test(val) {
  return Math.ceil(val);
}
